<template>
  <div class="workspace">
    <NavbarHomepage :isLogin="true" />
    <div class="row">
      <div class="slidebar col-md-3" style="left: 10px">
        <h4>可选取的列表</h4>
        <hr />
        <div class="select-devicetype-area">
          <div class="btn-group" role="group" aria-label="Basic example">
            <button
              type="button"
              class="btn btn-outline-primary"
              v-on:click="selectDeviceIndex = 0"
            >
              网络设备
            </button>
            <button
              type="button"
              class="btn btn-outline-success"
              v-on:click="selectDeviceIndex = 1"
            >
              终端设备
            </button>
            <button
              type="button"
              class="btn btn-outline-secondary"
              v-on:click="selectDeviceIndex = 2"
            >
              攻击节点
            </button>
            <button
              type="button"
              class="btn btn-outline-secondary"
              v-on:click="selectDeviceIndex = 3"
            >
              节点操作
            </button>
          </div>
        </div>
        <br />
        <div class="select-device-area">
          <div class="row" v-if="selectDeviceIndex == 0">
            <div
              class="col-md-6"
              v-for="ele in netDevices"
              :key="ele.id"
              v-on:click="selectDevice(0, ele)"
            >
              <div class="select-device">
                <DeviceImage
                  :group="0"
                  :type="ele.type"
                  :id="0 + ':' + ele.id"
                ></DeviceImage>
                <div class="select-device-name">{{ ele.name }}</div>
              </div>
            </div>
          </div>
          <div class="row" v-if="selectDeviceIndex == 1">
            <div
              class="col-md-6"
              v-for="ele in endDevices"
              :key="ele.id"
              v-on:click="selectDevice(1, ele)"
            >
              <div class="select-device">
                <DeviceImage
                  :group="1"
                  :type="ele.type"
                  :id="1 + ':' + ele.id"
                ></DeviceImage>
                <div class="select-device-name">{{ ele.name }}</div>
              </div>
            </div>
          </div>
          <div class="row" v-if="selectDeviceIndex == 2">
            <div
              class="col-md-6"
              v-for="ele in atkDevices"
              :key="ele.id"
              v-on:click="selectDevice(2, ele)"
            >
              <div class="select-device">
                <DeviceImage
                  :group="2"
                  :type="ele.type"
                  :id="2 + ':' + ele.id"
                ></DeviceImage>
                <div class="select-device-name">{{ ele.name }}</div>
              </div>
            </div>
          </div>
          <div class="row" v-if="selectDeviceIndex == 3">
            <div class="col-md-6" v-on:click="selectLine()">
              <div class="select-device">
                <DeviceImage
                  :group="3"
                  :type="0"
                  :id="3 + ':' + 0"
                ></DeviceImage>
                <div class="select-device-name">创建连线</div>
              </div>
            </div>
          </div>
        </div>
        <div class="show-select-area">
          {{ selectItemString }}
          <br />
          <div class="select-devicetype-area">
            <div class="btn-group" role="group" aria-label="Basic example">
              <button
                type="button"
                class="btn btn-success"
                v-on:click="saveWork()"
              >
                保存
              </button>
              <button
                type="button"
                class="btn btn-primary"
                v-on:click="runWork()"
              >
                开始运行
              </button>
              <button type="button" class="btn btn-danger" v-on:click="back()">
                返回
              </button>
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-9">
        <div class="deploy-area">
          <h4>{{ projectName }}</h4>
          <hr />
          <canvas
            width="650"
            height="500"
            id="oCanvasGrid"
            z-index="2"
            class="canvasModule"
          ></canvas>
          <canvas
            width="650"
            height="500"
            id="oCanvas"
            z-index="1"
            class="canvasModule"
          ></canvas>
        </div>
        <div class="operation-area" v-if="display">
          <ChooseMoteInfo :mote="choose.a" :select="select"></ChooseMoteInfo>
        </div>
      </div>
    </div>
    <img src="@/assets/target.png" id="img_target" style="display: none" />
  </div>
</template>

<script>
import NavbarHomepage from "@/components/NavbarHomepage.vue";
import DeviceImage from "@/components/DeviceImage.vue";
import ChooseMoteInfo from "@/components/ChooseMoteInfo.vue";

import {
  canvasClickEventHandler,
  canvasHoverEventHandler,
  setDataIntoCanvasModule,
  runloop,
  RUNLOOPTIME,
  ATTACKTIME,
} from "@/module/canvasModule.js";

import {
  SELECTNONE,
  SELECTMOTE,
  SELECTLINE,
  SELECTREMOVEMOTE,
  SELECTREMOVELINE,
  CHOOSEATTACK,
  DEFENCESTANDARD,
  DEFENCEML,
  DEFENCEDL,
  STATUS_ERR,
  STATUS_NORMAL,
} from "@/module/name.js";

export default {
  name: "Dashboard",
  components: {
    NavbarHomepage,
    DeviceImage,
    ChooseMoteInfo,
  },
  data: function () {
    return {
      selectDeviceIndex: 0,
      netDevices: [
        {
          id: 1,
          type: 0,
          name: "NCS 520",
        },
        {
          id: 2,
          type: 0,
          name: "NCS 540",
        },
        {
          id: 3,
          type: 1,
          name: "NCS 560",
        },
      ],
      endDevices: [
        {
          id: 1,
          type: 0,
          name: "立净洗衣机",
        },
        {
          id: 2,
          type: 0,
          name: "西门子洗衣机",
        },
        {
          id: 3,
          type: 1,
          name: "捷顺智能门禁",
        },
        {
          id: 4,
          type: 2,
          name: "小爱同学",
        },
        {
          id: 5,
          type: 2,
          name: "天猫精灵",
        },
      ],
      atkDevices: [
        {
          id: 1,
          type: 0,
          name: "笔记本",
        },
      ],
      /**
       * 存储从列表中的选择动作
       */
      select: {
        group: null,
        item: null,
        entity: null,
        type: SELECTNONE,
      },
      /**
       * 存储中绘图模块中的选择动作
       * choose.a 通常也表示被选择的一个节点
       * display默认展示的也是 choose.a
       */
      choose: {
        /**
         * {
         *  id:0,
         *  x:0,
         *  y:0,
         *  group:0,
         *  item:0
         * }
         */
        a: null,
        b: null,
      },
      display: false,
      show: {},
      canvasModule: {
        /**
         * {
         *  id:0,
         *  x:0,
         *  y:0,
         *  group:0,
         *  item:0,
         *  entity:null,
         *  info:{
         *    name:"",
         *    defenceType:0,
         *    feature:null
         *    almodel:null
         *    mlmodel:null,
         *  },
         *  isAttackNode: false,
         *  isEndDevice: false,
         *  attackerId:0,
         *  status:0
         * }
         */
        motes: [],
        /**
         * {
         *  id:0,
         *  aid:0,
         *  bid:0,
         *  ax:0,
         *  ay:0,
         *  bx:0,
         *  by:0
         * }
         */
        lines: [],
      },
      idCounter: {
        mote: 1,
        line: 1,
      },
      oCanvas: null,
      ctx: null,
      imgs: {
        target: null,
      },
      /**
       * 当前workspace的仿真模块是否启动
       */
      isRunning: false,
      runningSeconds: 0,
      projectName: "",
    };
  },
  methods: {
    /**
     * 从列表中，选取了一个节点对象
     * 之后可以用来添加到canvas模块中
     */
    selectDevice: function (eleGroup, ele) {
      this.select.type = SELECTMOTE;
      this.select.item = ele;
      this.select.group = eleGroup;
      this.select.entity = document.getElementById(eleGroup + ":" + ele.id);
      this.choose.a = null;
      this.choose.b = null;
      this.display = false;
    },
    /**
     * 取消在列表中选取的节点对象
     */
    cancelDevice: function () {
      this.select.type = SELECTNONE;
      this.select.item = null;
      this.select.group = null;
      this.select.entity = null;
      this.choose.a = null;
      this.choose.b = null;
      this.display = false;
    },
    selectLine: function () {
      this.select.type = SELECTLINE;
    },
    saveWork: function () {
      console.log("Save Work");
    },
    runWork: function () {
      this.isRunning = true;
      setInterval(function () {
        runloop();
      }, RUNLOOPTIME);
    },
    back: function () {
      console.log("Back");
      this.$router.push("/dashboard");
    },
    /**
     * 被选中的select
     * 会被添加到canvasModule的motes中去
     */
    canvasCallbackAddMote: function (e) {
      this.canvasModule.motes.push({
        id: this.idCounter.mote,
        x: e.layerX,
        y: e.layerY,
        group: this.select.group,
        item: this.select.item,
        entity: this.select.entity,
        info: {
          name: "Mote " + this.idCounter.mote,
          defenceType: DEFENCEDL,
          feature: null,
          mlmodel: null,
          almodel: null,
        },
        isAttackNode: this.select.group == 2,
        isEndDevice: this.select.group == 1,
        attackerId: 0,
        status: STATUS_NORMAL,
      });
      this.idCounter.mote++;
      console.log(this.canvasModule.motes);
    },
    /**
     * 触发添加逻辑
     * choose中的a,b 都会被添加
     */
    canvasCallbackAddLine: function () {
      if (this.choose.a != this.choose.b) {
        this.canvasModule.lines.push({
          id: this.idCounter.line++,
          aid: this.choose.a.id,
          bid: this.choose.b.id,
          ax: this.choose.a.x,
          ay: this.choose.a.y,
          bx: this.choose.b.x,
          by: this.choose.b.y,
        });
        console.log(
          "Add Line between " + this.choose.a.id + " to " + this.choose.b.id
        );
      } else {
        console.log("Can't add Line between the same Mote");
      }
      this.cancelDevice();
    },
    /**
     * 触发攻击逻辑
     * choose.a 攻击 choose.b
     */
    canvasCallbackAddAttack: function () {
      this.choose.b.attackerId = this.choose.a.id;
      this.cancelDevice();
    },
    /**
     * 每过 RUNLOOPTIME = 50 就会调用一次
     */
    canvasCallbackLoop: function () {
      this.runningSeconds += RUNLOOPTIME;
      if (this.runningSeconds > ATTACKTIME) {
        let motes = this.canvasModule.motes;
        for (let i = 0; i < motes.length; i++) {
          const mote = motes[i];
          if (mote.attackerId != 0 && !this.checkHasDefence(mote)) {
            //如果当前节点被攻击 并且没有携带防御措施
            console.log(mote);
            mote.status = STATUS_ERR;
          }
        }
      }
    },
    checkHasDefence: function (mote) {
      if (
        mote.info.defenceType == DEFENCESTANDARD &&
        mote.info.feature != null
      ) {
        return true;
      } else if (
        mote.info.defenceType == DEFENCEML &&
        mote.info.almodel != null
      ) {
        return true;
      } else if (
        mote.info.defenceType == DEFENCEDL &&
        mote.info.dlmodel != null
      ) {
        return true;
      }
      return false;
    },
  },
  computed: {
    selectItemString: function () {
      if (this.select.type == SELECTMOTE) {
        return this.select.item.name + " has been selected";
      } else if (this.select.type == SELECTLINE) {
        let str = "create Line from ";
        if (this.choose.a != null) {
          str += this.choose.a.id;
        }
        if (this.choose.b != null) {
          str += " to " + this.choose.b.id;
        }
        return str;
      } else if (this.select.type == CHOOSEATTACK) {
        return this.choose.a.info.name + " ready to attack ";
      }
    },
  },
  created: function () {
    this.projectName = this.$route.query.name;
    if (this.projectName == null) {
      this.$router.push("/");
    }
    let _this = this;
    document.onkeydown = function (e) {
      if (e.key == "Escape") {
        _this.cancelDevice();
      }
    };
  },
  mounted: function () {
    this.oCanvas = document.getElementById("oCanvas");
    this.oCanvasGrid = document.getElementById("oCanvasGrid");
    this.ctx = this.oCanvas.getContext("2d");
    this.imgs.target = document.getElementById("img_target");
    setDataIntoCanvasModule(
      this,
      this.oCanvas,
      this.oCanvasGrid,
      this.ctx,
      this.select,
      this.choose,
      this.canvasModule
    );
    this.oCanvas.addEventListener("mouseup", function (e) {
      canvasClickEventHandler(e);
    });
    this.oCanvas.addEventListener("mousemove", function (e) {
      canvasHoverEventHandler(e);
    });
  },
};
</script>

<style scoped>
.slidebar {
  top: 15px;
}
.slide-item {
  color: blueviolet;
  font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
  margin-top: 20px;
  cursor: pointer;
}

.canvasModule {
  top: 70px;
  left: 10px;
  position: absolute;
}

.deploy-area {
  width: 70%;
  height: 550px;
  position: absolute;
  border-radius: 5px;
  text-align: center;
}
.deploy-area h4 {
  top: 12px;
  left: 38%;
  position: absolute;
}
.deploy-area hr {
  left: 20%;
  top: 40px;
  position: absolute;

  width: 50%;
}
.operation-area {
  left: 70%;
  width: 25%;
  height: 550px;
  position: absolute;
}

.select-device-area {
  height: 400px;
}
.show-select-area {
  left: 10px;
  position: relative;
}
.select-device {
  height: 100px;
  border-radius: 10px;
}
.select-device-name {
  font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
}
.select-device:hover {
  background-color: blueviolet;
  transition: all 0.2s;
}
.select-device:active {
  background-color: red;
  transition: all 0.2s;
}
</style>